<?php
require_once 'Zend/View/Helper/Url.php';
$uml = new PlainTextUml(Zend_View_Helper_Url);
echo "<pre>";
foreach ($uml->classDiagram() as $l) {
	echo $l . "\n";
}
echo "</pre>";


class PlainTextUml {
	
	const PARAM_MODE_NONE       = 0;
	const PARAM_MODE_NAME_ONLY  = 1;
	const PARAM_MODE_POSITION   = 2;
	
	
	private $_name;
	private $_fields = array();
	private $_methods = array();
	private $_options;
  
	function __construct($className, $options = array("param_mode" => PARAM_MODE_NAME_ONLY)) {
		$this->_options = $options;
		$this->_name = $className;
		$class = new ReflectionClass($className);
		$show_inherited = $options["show_inherited"];
		/* @var $prop ReflectionProperty */
		foreach ($class->getProperties() as $prop) {
			$modifier = "";
			if ($prop->isStatic()) {
				$modifier .= "$";
			}
			
			if ($prop->isPublic()) {
				$modifier .= "+";
			} else if ($prop->isProtected()) {
				$modifier .= "#";
			} else if ($prop->isPrivate()) {
				$modifier .= "-";
			}  
			
			if ($show_inherited || $this->_name == $prop->getDeclaringClass()->getName()) {
				$this->_fields[] = $modifier . " " . $prop->getName();
			}  
		}
		
		/* @var $m ReflectionMethod */
		foreach ($class->getMethods() as $m) {
			$modifier = "";
			if ($m->isStatic()) {
				$modifier .= "$";
			}
			
			if ($m->isPublic()) {
				$modifier .= "+";
			} else if ($m->isProtected()) {
				$modifier .= "#";
			} else if ($m->isPrivate()) {
				$modifier .= "-";
			}  
			
			$param_str = "(";  
			$i = 0;
			// make method parameters string
			
			
			foreach ($m->getParameters() as $p) {
				if (PARAM_MODE_NAME_ONLY == $this->_options["param_mode"]) {
					if ($i == 0) {
						$param_str .= $p->name;
					}else {
						$param_str = $param_str . ", " . $p->name;
					} 
				} else if (PARAM_MODE_NONE == $this->_options["param_mode"]) {
						// don't show param
						$param_str .= '';
				} else if (PARAM_MODE_POSITION == $this->_options["param_mode"]) {
					if ($i == 0) {
						$param_str = $param_str . 'p' . ($i + 1);
					}else {
						$param_str = $param_str . ', ' . 'p' . ($i + 1);
					} 					
				}
				$i++;
			}
			$param_str .=")";
			if ($show_inherited || $this->_name == $m->getDeclaringClass()->getName()) {
				if ($this->_name != $m->getDeclaringClass()->getName() && $m->isPrivate()) {
					continue;
				}
				$this->_methods[] = $modifier . " " . $m->getName() . $param_str;
			}  
		}
	}
 
	public function getName() {
		return $this->_name;
	}
    
	public function getFields() {
		return $this->_fields;
	}
  
	public function getMethods() {
		return $this->_methods;
	}
	
	public function classDiagram() {
		$split = '+' . str_repeat('-', $this->getMaxLenth() + 2) . '+';
		// class name
		$results[] = $split;
		$results[] = '| ' . str_pad($this->_name, $this->getMaxLenth(), ' ', STR_PAD_BOTH) . ' |';
		$results[] = $split;
		// fields
		foreach ($this->_fields as $f) {
			$results[] = '| ' . str_pad($f, $this->getMaxLenth(), ' ') . ' |';
		}
		$results[] = $split;
		// method
		foreach ($this->_methods as $m) {
			$results[] = '| ' . str_pad($m, $this->getMaxLenth(), ' ') . ' |';
		}
		$results[] = $split;
		return $results;
	}
	
	public function getMaxLenth() {
		$max_len = strlen($this->_name);
		
		foreach ($this->getFields() as $f) {
			if (strlen($f) > $max_len) {
				$max_len = strlen($f); 
			}
		}

		foreach ($this->getMethods() as $m) {
			if (strlen($m) > $max_len) {
				$max_len = strlen($m); 
			}
		}
		return $max_len;
	}
	
}